package org.uni_hi.muus.server.http;

import java.io.DataInputStream;
import java.io.IOException;

import org.uni_hi.muus.util.StringUtil;

public class HTTPStreamParser {
	
	private Header _header=null;
	private DataInputStream _din=null;
	
	final static int BUF_LEN = 2048;
	char[] buf = new char[BUF_LEN];
	int pos;
	StringBuffer lineBuf;
	
	public HTTPStreamParser(Header header, DataInputStream din){
		_header=header;
		_din=din;
	}
		
	public String getStartLine() throws IOException{
		String startLine="";
		do {
			startLine = readLine();
			/* skip blank lines */
		} while (startLine.equals(""));
		return startLine;
	}
	
	protected String readLine() throws IOException {
		boolean gotCR = false, gotLF = false;
		pos = 0;
		lineBuf = new StringBuffer();
		buf=new char[BUF_LEN];
		while (!gotLF) {
			int c = _din.read();
			if (c == -1) {
				return null;
			}
			if (gotCR) {
				if (c == StringUtil.LF) {
					gotLF = true;
				} else {
					gotCR = false;
					consume(StringUtil.CR);
					consume(c);
				}
			} else {
				if (c == StringUtil.CR) {
					gotCR = true;
				} else {
					consume(c);
				}
			}
		}
		lineBuf.append(buf, 0, pos);
		return new String(lineBuf);
	}
	
	private int consume(int c) {
		if (pos == BUF_LEN) {
			lineBuf.append(buf);
			pos = 0;
		}
		buf[pos++] = (char) c;
		return pos;
	}
	
	public void readDataInputStream() throws IOException{
		char s[] = new char[10];
		int firstc = _din.read();
		while (firstc != StringUtil.LF && firstc != StringUtil.CR && firstc >= 0) {
			int len = 0;
			int keyend = -1;
			int c;
			boolean inKey = firstc > ' ';
			s[len++] = (char) firstc;
			parseloop: {
				while ((c = _din.read()) >= 0) {
					switch (c) {
					case ':':
						if (inKey && len > 0)
							keyend = len;
						inKey = false;
						break;
					case '\t':
						c = ' ';
					case ' ':
						inKey = false;
						break;
					case StringUtil.CR:
					case StringUtil.LF:
						firstc = _din.read();
						if (c == StringUtil.CR && firstc == StringUtil.LF) {
							firstc = _din.read();
							if (firstc == StringUtil.CR)
								firstc = _din.read();
						}
						if (firstc == StringUtil.LF || firstc == StringUtil.CR
								|| firstc > ' ')
							break parseloop;
						/* continuation */
						c = ' ';
						break;
					}
					if (len >= s.length) {
						char ns[] = new char[s.length * 2];
						System.arraycopy(s, 0, ns, 0, len);
						s = ns;
					}
					s[len++] = (char) c;
				}
				firstc = -1;
			}
			while (len > 0 && s[len - 1] <= ' ')
				len--;
			String k;
			if (keyend <= 0) {
				k = null;
				keyend = 0;
			} else {
				k = String.valueOf(s, 0, keyend);
				if (keyend < len && s[keyend] == ':')
					keyend++;
				while (keyend < len && s[keyend] <= ' ')
					keyend++;
			}
			String v;
			if (keyend >= len)
				v = new String();
			else
				v = String.valueOf(s, keyend, len - keyend);
			_header.addValuePair(k, v);
		}
	}
}
